package us.gaaoc.framework.signature.visual;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import us.gaaoc.cms.sustain.vo.CaseDocument;
import us.gaaoc.framework.manager.DocumentStatusManager;
import us.gaaoc.framework.model.Documents;
import us.gaaoc.framework.signature.digital.DigitalSignerController;
import us.gaaoc.framework.webapp.backingbeans.BaseBackingBean;

/**
 * 
 * @author alexandrm
 * @date September 23rd 2007
 * @version: GAJE 2.0x
 * 
 */
public class DocumentStamping extends BaseBackingBean implements Serializable {
	
	private Map sessionMap = this.getFacesContext().getExternalContext().getSessionMap();
	private DocumentStatusManager documentStatusManager;
	private static transient Logger LOG = Logger
		.getLogger(DocumentStamping.class);
	/**
	 * Constructor
	 * 
	 */
	public DocumentStamping() {
		LOG.debug("The documentStamping object has been created");
		
	}
	
	
	
	public ArrayList<CaseDocument> createCaseDocumentListFromDocumentList(
			List<Documents> documentListPassedIn) {
		// Convert docs into format needed for import into Sustain
		ArrayList<CaseDocument> pdfDocList = new ArrayList<CaseDocument>();
		for (Documents doc : documentListPassedIn) {
			CaseDocument pdfDoc = new CaseDocument();
			pdfDoc.setContent(doc.getContent());
			pdfDoc.setTitle(doc.getTitle());
			pdfDoc.setType(doc.getDocumentInstance().getDocLocalCode()
					.getCode());
			pdfDocList.add(pdfDoc);
		}
		return pdfDocList;
	}
	
	public CaseDocument createCaseDocumentFromDocument(
			Documents documentPassedIn) {
		// Convert doc into format needed for import into Sustain
		CaseDocument pdfDoc = new CaseDocument();
		pdfDoc.setContent(documentPassedIn.getContent());
		pdfDoc.setTitle(documentPassedIn.getTitle());
		pdfDoc.setType(documentPassedIn.getDocumentInstance().getDocLocalCode()
				.getCode());
		return pdfDoc;
	}
	
  /*
	 * For a document to get the court received stamp the following must be
	 * satisfied: The document must have contents
	 *  if document has contents
	 *  	if document is of type 34 or 27 
	 *  		then the document must be of status "signedByClerk" (code=8)
	 *  Three possible return strings
	 *  	noContentsDocument
	 *  	documentListNotSignedByClerk
	 *  	documentsReadyForCourtReceivedStamp
	 */
	public int documentsReadyForCourtReceivedStamp(
			List<Documents> documentList) {		
		LOG.debug("Check if the douments are all with non null contents");
		
		int returnString = 0;
	
		if (documentWithNoContents(documentList)) {			
			returnString = documentStatusManager.getStatusCode();
		} else {
			LOG.debug("There are no docs without contents, next we check the docs for clerk signature");
			List <Documents> dnsbclerk = (documentListNotSignedByClerk(documentList));
			if(this.docNotSignedByClerk(dnsbclerk) ){
				returnString = documentStatusManager.getStatusCode();
			}else if(this.docsSignedByClerk(dnsbclerk)){
				returnString = documentStatusManager.getStatusCode();
			}
		}
		LOG.debug("The method documentsReadyForCourtReceivedStamp returns "+returnString);
		//for DEBUG PURPOSES ONLY
		//returnString = "documentListNotSignedByClerk";
		return returnString;
	}
	/*
	 * Up to the point where the clerk signs the documents a document 
	 * can be of statusCode 6, for upload or 11 for attorney signed document
	 * After the clerk signs the proper documents....
	 * To get the list of documents where the sign function 
	 * of the clerk failed we only need to examine the statusCode of only
	 * the documents a clerk signs. If the statusCode of a doc is different 
	 * than 8 then append the doc to the list of documents of failed clerk signatures
	 * 
	 * 
	 * Error found:  Document changes states after being signed by the Clerk.  
	 * Since we are using only single states at this moment, the method below 
	 * becomes invalid on second runs when an error is incurred.  If using 
	 * action logs, then this would still work, but until then, we need an 
	 * alternate way to check for if a document is signed by the Court Clerk.
	 * Using a method from the "Case Details" class used to determine whether to
	 * render the "Sign" button or not.
	 *  
	 */
	public List<Documents> documentListNotSignedByClerk(List<Documents> documentList){
		
		// Method Variables
		List<Documents> docLisNotSignedByClerk = new ArrayList<Documents>();
		DigitalSignerController digitalSignerController = new DigitalSignerController();
		
		LOG.debug("checking the proper documents for signature by the clerk ");
	
		for (Documents doc : documentList) {
			if (doc.getPhysicalType().equalsIgnoreCase("pdf")) {									
				if ( ( (doc.getDocumentInstance().getDocumentType().getCode() == 30034)
						|| ((doc.getDocumentInstance().getDocumentType().getCode() == 30027 && (doc.getDocumentInstance().getCode() != 300610))) 
						) && !doc.getDocumentInstance().getCourt().getUuid().equalsIgnoreCase("courtUuidBibb")
						 && !doc.getDocumentInstance().getCourt().getUuid().equalsIgnoreCase("courtUuid5")) {	
					//THE FOLLOWING FOUR LINES ARE FOR DEBUGGING PURPOSES ONLY. When executing application comment the below four lines out
					//DocumentStatus ds = new DocumentStatus();
					//ds.setCode(1);
					//ds.setDescription("received");
					//doc.setStatus(ds);
					LOG.debug("the doc " + doc.getTitle()+" is checked for signature by the clerk ");	
					/*
					if (doc.getStatus().getCode() != 8) {
						docLisNotSignedByClerk.add(doc);
						
					}
					*/
					boolean signedByClerkDoc = digitalSignerController.isDocumentOrderForClerk(doc);
					if (!signedByClerkDoc) {
						docLisNotSignedByClerk.add(doc);
					}
					LOG.debug("the doc " + doc.getTitle()
							+ " is signed by the clerk ");
				}
			}
		}
		return docLisNotSignedByClerk;
	}
	
	public boolean docNotSignedByClerk(List<Documents> docsNotSigned) {
		boolean notSigned = false;
		if(docsNotSigned.size() >= 1) {
			notSigned = true;
			documentStatusManager = new DocumentStatusManager(2,"documentListNotSignedByClerk");
			LOG.debug("Some Documents are not signed by Clerk");		
		}
		return notSigned;
	}
	
	public boolean docsSignedByClerk(List<Documents> docsNotSigned) {
		boolean allSigned = false;
		if(docsNotSigned.size() == 0) {
			allSigned = true;
			documentStatusManager = new DocumentStatusManager(3,"documentsReadyForCourtReceivedStamp");
			LOG.debug("Documents are Ready to Stamp");		
		}
		return allSigned;
	}
	
	public boolean docWithoutCourtReceivedStamp(List<Documents> docs) {
		boolean docsWithStamps = false;
		if(docs.size() >= 1) {
			docsWithStamps = true;
			documentStatusManager = new DocumentStatusManager(4,"documentListWithoutCourtReceivedStamp");
			LOG.debug("Some Documents are withour court received stamp");		
		}
		return docsWithStamps;
	}
	
	public boolean docsWithCourtReceivedStamp(List<Documents> docsNotStamped) {
		boolean docsWithStamp = false;
		if(docsNotStamped.size() == 0) {
			docsWithStamp = true;
			documentStatusManager = new DocumentStatusManager(5,"documentsReadyForCivilActionNumberStamp");
			LOG.debug("Documents are Ready For Civil Action Number");		
		}
		return docsWithStamp;
	}
	 /*
		 * For a document to get the civil action number stamp 
		 * the following must be satisfied: the document must have contents 
		 * 	and the document must be of status "courtReceivedStamp"
		 *  or the document is the Sheriff's Entry of Service 
		 *  Possible string returns
		 *  	noContentsDocument
		 *  	documdentWithNoCourtReceivedStamp
		 *  	documentsReadyForCivilActionNumberStamp
		 *  
		 */
	public int documentsReadyForCivilActionNumberStamp(
			List<Documents> documentListPassedIn) {
		LOG.debug("Check if the douments are all with non null contents");
		int returnString = 0;			
		if (documentWithNoContents(documentListPassedIn)) {
			returnString = documentStatusManager.getStatusCode();
		} else {
			List<Documents> docListWithoutCourtReceivedStamp = documentListWithoutCourtReceivedStamp(documentListPassedIn);
			if(this.docWithoutCourtReceivedStamp(docListWithoutCourtReceivedStamp)){
				//returnString = "documdentWithNoCourtReceivedStamp";
				returnString = documentStatusManager.getStatusCode();
			}else if(docsWithCourtReceivedStamp(docListWithoutCourtReceivedStamp)){
				//returnString = "documentsReadyForCivilActionNumberStamp";
				returnString = documentStatusManager.getStatusCode();
			}
		}
		return returnString;
	}
	
	
	public List<Documents> documentListWithoutCourtReceivedStamp(List<Documents> documentList){
		List<Documents> docListWithoutCourtReceivedStammp = new ArrayList<Documents>();
		for (Documents doc : documentList) {
			if (doc.getPhysicalType().equalsIgnoreCase("pdf")) {
				LOG.debug("checking this doc " + doc.getTitle()
						+ " for court received stamp ");	
				//exclude the doc that are not suppose to have the court received stamp
				//check if the status code is not 9
				if(doc.getPhysicalType().equalsIgnoreCase("pdf")
						&& (doc.getDocumentInstance().getCode() != 181)
						&& (doc.getDocumentInstance().getCode() != 1)
						&& (doc.getDocumentInstance().getCode() != 107)
						&& (doc.getDocumentInstance().getCode() != 108)
						&& (doc.getDocumentInstance().getCode() != 35)
						&& (doc.getDocumentInstance().getCode() != 173)
						&& (doc.getDocumentInstance().getCode() != 162)
						&& (doc.getDocumentInstance().getCode() != 156)
						&& (doc.getDocumentInstance().getCode() != 197)
						&& (doc.getDocumentInstance().getCode() != 196)
						) {					
					if (doc.getStatus().getCode() == 12) {
						docListWithoutCourtReceivedStammp.add(doc);
					}
				}
			}
		}
		return docListWithoutCourtReceivedStammp;
	}
	public List<Documents> documentListWithoutContents (List<Documents> documentList){
		List<Documents> docListWithoutContents = new ArrayList<Documents>();
		for (Documents doc : documentList) {
			if(doc.getContent() == null){
				docListWithoutContents.add(doc);
			}
		}
		return docListWithoutContents;
	}
	/**
	 * check if the documentlist contains a doc with no contents
	 */
	public boolean documentWithNoContents(List<Documents> documentList){
		boolean retBoolean = false;
		
		for (Documents doc : documentList) {
			if(doc.getContent() == null){
				retBoolean = true;
				documentStatusManager = new DocumentStatusManager(1,"noContentsDocument");
				LOG.debug("This doc "+doc.getTitle()+" has no contents");
			}
		}
		return retBoolean;
	}
	
		
	/**
	 * This method checks whether documents are stamped for the Court Received stamp and the Digitally Signed.
	 * @param documentListPassedIn
	 * @return
	 */
	public boolean checkDocumentListForCourtReceivedStamp(
			List<Documents> documentListPassedIn) {
		// TODO Is this transaction needed?  If so, where does it end?
		// HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().begin();
		int count = 0;
		  while(count<=documentListPassedIn.size()-1){
			  int documentInstanceCode = documentListPassedIn.get(count).getDocumentInstance().getCode();
			  int documentStatusCode = documentListPassedIn.get(count).getStatus().getCode();
			  if ((documentInstanceCode != 181)						//Sheriff's Entry of Service - Filed - Bibb
					  && (documentInstanceCode != 1)){				//Acknowledgment of Service
				  				if (documentStatusCode != 9) {		//Stamped with court received stamp
			                              return false;
				  					}
			          }
			  	count++;                        
			  }
			  return true;
	}
		
	/**
	 * This method checks whether documents are stamped with the Civil Action Number Stamp
	 * @param documentListPassedIn
	 * @return
	 */
	public boolean checkDocumentListForCivilActionNumberStamp(List<Documents> documentListPassedIn) {
		//start the transaction
		//HibernatePhaseListener.getSessionFactory().getCurrentSession().getTransaction().begin();
		int count = 0;		
		while(count<=documentListPassedIn.size()-1){
			/*
			DocumentInstance documentInstance = new DocumentInstance();
			documentInstance = documentListPassedIn.get(count).getDocumentInstance();
			int documentInstanceCode = documentInstance.getCode();
			int documentTypeCode = documentInstance.getDocumentType().getCode();
			if ((documentInstanceCode != 181)						//Sheriff's Entry of Service - Filed - Bibb		
					&& (documentInstanceCode != 1)					//Acknowledgment of Service
					&& (documentTypeCode != 11)){					// Initiation Form of File
						if (documentListPassedIn.get(count).getStatus().getCode() != 10) {		//Added docket ID
								return false;
						}
			}*/
			if(documentListPassedIn.get(count).getStatus().getCode() != 9) {	//Added Court Stamp, Docket ID and Digital Signature on the document
				return false;
			}
			count++;			
		}
		return true;
	}
}
